package com.xinchao.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.xinchao.cache.RedisCacheDao;
import com.xinchao.constant.CacheConstant;
import com.xinchao.constant.DateConstant;
import com.xinchao.exception.ServiceException;
import com.xinchao.model.dto.AdvertisementExposuresTouchWatchSumDTO;
import com.xinchao.model.dto.AdvertisementMonitorSumDTO;
import com.xinchao.model.vo.IndexAdvertisementMonitorSumVO;
import com.xinchao.model.vo.IndexExposuresTouchWatchSumVO;
import com.xinchao.service.AdvertisementMonitorService;
import com.xinchao.service.IndexService;
import com.xinchao.util.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * 首页Service
 * @author dxy
 * @date 2018/9/29 15:10
 */
@Service(value = "indexService")
public class IndexServiceImpl implements IndexService{
	@Autowired
	private AdvertisementMonitorService advertisementMonitorService;
	@Autowired
	private RedisCacheDao redisCacheDao;

	/**
	 * 获取首页曝光次数、触达人次、观看人次、平均观看时长、点位数
	 *
	 * @param dateType 日期类型（0：今日；1：明日；2：近7天；3：近30天）
	 * @return IndexAdvertisementMonitorSumVO
	 * @throws ServiceException
	 */
	@Override
	public IndexAdvertisementMonitorSumVO getIndexAdvertisementMonitorSumVO(Integer dateType) throws ServiceException, ParseException {
		if (dateType == null) {
			throw new ServiceException("输入参数为空");
		}
		//开始时间
		Long startTime = null;
		//结束时间
		Long endTime = null;
		//今天
		if (DateConstant.TODAY == dateType) {
			//当前时间戳
			long currentTimeMillis = System.currentTimeMillis();
			//当前年月日
			String yearMonthDay = DateUtils.longTimeStampToStringDate(currentTimeMillis, DateConstant.DATE_SHORT_ISO);
			String startTimeStr = yearMonthDay + DateConstant.H_M_S_MIN;
			startTime = DateUtils.stringTimeToLongTimeStamp(startTimeStr, DateConstant.LONG_DATE_FORMAT_STR);
			endTime = currentTimeMillis;
		}
		//昨天
		if (DateConstant.YESTERDAY == dateType) {
			//获取昨天年月日
			String yearMonthDay = DateUtils.getPastDay(1, DateConstant.DATE_YEAR_MONTH_DAY);
			String startTimeStr = yearMonthDay + DateConstant.H_M_S_MIN;
			String endTimeStr = yearMonthDay + DateConstant.H_M_S_MAX;
			startTime = DateUtils.stringTimeToLongTimeStamp(startTimeStr, DateConstant.DATE_YEAR_MONTH_DAY_HMS);
			endTime = DateUtils.stringTimeToLongTimeStamp(endTimeStr, DateConstant.DATE_YEAR_MONTH_DAY_HMS);
		}
		//近7天
		if (DateConstant.RECENT_SEVEN_DAY == dateType) {
			endTime = System.currentTimeMillis();
			//获取昨天年月日
			String yearMonthDay = DateUtils.getPastDay(6, DateConstant.DATE_YEAR_MONTH_DAY);
			String startTimeStr = yearMonthDay + DateConstant.H_M_S_MIN;
			startTime = DateUtils.stringTimeToLongTimeStamp(startTimeStr, DateConstant.DATE_YEAR_MONTH_DAY_HMS);
		}
		//近30天
		if (DateConstant.RECENT_THIRTY_DAY == dateType) {
			endTime = System.currentTimeMillis();
			//获取昨天年月日
			String yearMonthDay = DateUtils.getPastDay(29, DateConstant.DATE_YEAR_MONTH_DAY);
			String startTimeStr = yearMonthDay + DateConstant.H_M_S_MIN;
			startTime = DateUtils.stringTimeToLongTimeStamp(startTimeStr, DateConstant.DATE_YEAR_MONTH_DAY_HMS);
		}
		//曝光次数、触达人次、观看人次、平均观看时长
		AdvertisementMonitorSumDTO dto = advertisementMonitorService.getAdvertisementMonitorSumByTime(null, startTime, endTime, null);
		IndexAdvertisementMonitorSumVO vo = new IndexAdvertisementMonitorSumVO();
		if (dto == null) {
			//曝光次数
			vo.setExposuresSum(0D);
			//触达人次
			vo.setTouchSum(0D);
			//观看人次
			vo.setWatchSum(0D);
			//总时长
			vo.setWatchAvg("0");
			vo.setDeviceNum(0);
		} else {
			//曝光次数
			vo.setExposuresSum(dto.getExposuresSum());
			//触达人次
			vo.setTouchSum(dto.getTouchSum());
			//观看人次
			Double watchSum = dto.getWatchSum();
			vo.setWatchSum(watchSum);
			//总时长
			Double playDurationSum = dto.getPlayDurationSum();
			if (playDurationSum == null) {
				playDurationSum = 0D;
			}
			double duration = playDurationSum / 1000;
			//平均观看时长=总时长/总观看人次(单位为秒)
			if (watchSum == null || watchSum == 0) {
				vo.setWatchAvg("0");
			} else {
				double watchAvg = duration / watchSum;
				vo.setWatchAvg(String.format("%.2f", watchAvg));
			}
			//点位数
			List<String> deviceNumberList = advertisementMonitorService.listDeviceNumberByTime(startTime, endTime);
			int size = deviceNumberList.size();
			vo.setDeviceNum(size);
		}
		return vo;
	}

	/**
	 * 获取曝光次数、触达人次、观看人次
	 * @return List<IndexExposuresTouchWatchSumVO>
	 */
	@Override
	public List<IndexExposuresTouchWatchSumVO> listExposuresTouchWatchSum() throws ParseException, ServiceException {
		List<IndexExposuresTouchWatchSumVO> voList = new ArrayList<>();
		//取最近30的数据（包含现在）
		int recentDayNum = 30;
		//获取近30天的日期数组
		String[] thirtyRecentDay = DateUtils.getRecentDay(recentDayNum, DateConstant.DATE_YEAR_MONTH_DAY);
		//日期按先后排列
		for (int i = thirtyRecentDay.length - 1; i >= 0; i--) {
			String day = thirtyRecentDay[i];
			IndexExposuresTouchWatchSumVO vo = new IndexExposuresTouchWatchSumVO();
			//从缓存中获取
			Object cache = redisCacheDao.getCache(CacheConstant.CACHE_NAME_ADVERTISEMENT_MONITOR, day);
			//如果缓存为空，从数据库中查询
			if (cache == null) {
				String startDay  = day + DateConstant.H_M_S_MIN;
				String endDay  = day + DateConstant.H_M_S_MAX;
				Long startTime = DateUtils.stringTimeToLongTimeStamp(startDay, DateConstant.DATE_YEAR_MONTH_DAY_HMS);
				Long endTime = DateUtils.stringTimeToLongTimeStamp(endDay, DateConstant.DATE_YEAR_MONTH_DAY_HMS);
				AdvertisementExposuresTouchWatchSumDTO dto = advertisementMonitorService.getAdvertisementExposuresTouchWatchSumByTime(startTime, endTime);
				if (dto != null) {
					vo.setTouchSum(dto.getTouchSum());
					vo.setExposuresSum(dto.getExposuresSum());
					vo.setWatchSum(dto.getWatchSum());
				}
			} else {
				JSONObject jsonObject = JSON.parseObject(cache.toString());
				Collection<Object> values = jsonObject.values();
				double touchSum = 0;
				double exposuresSum = 0;
				double watchSum = 0;
				for (Object obj : values) {
					if (obj == null) {
						continue;
					}
					AdvertisementMonitorSumDTO sumDTO = JSON.parseObject(obj.toString(), AdvertisementMonitorSumDTO.class);
					if (sumDTO == null) {
						continue;
					}
					Double touch = sumDTO.getTouchSum();
					Double exposures = sumDTO.getExposuresSum();
					Double watch = sumDTO.getWatchSum();
					if (touch != null) {
						touchSum = touchSum + touch;
					}
					if (exposures != null) {
						exposuresSum = exposuresSum + exposures;
					}
					if (watch != null) {
						watchSum = watchSum + watch;
					}
				}
				vo.setTouchSum(touchSum);
				vo.setExposuresSum(exposuresSum);
				vo.setWatchSum(watchSum);
				long end = System.currentTimeMillis();
			}
			vo.setTime(day);
			voList.add(vo);
		}
		return voList;
	}

}
